/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package eda.chl.johaolof.lsmtp;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SealedObject;

/**
 *
 * @author cjp
 */
public class SecureMail extends Mail {
    
    private byte[] msgPayload;
    private boolean encrypted = false;
    private byte[] msgSignature;
    private boolean signed = false;
    
    SecureMail(String to, String from, String subject, String message) {
        super(to,from,subject,message);
    }
    
    public void encrypt(PublicKey pubKey) throws 
            NoSuchAlgorithmException, 
            NoSuchPaddingException, 
            InvalidKeyException, 
            IllegalBlockSizeException, 
            BadPaddingException, 
            IOException {
        //System.out.println("Before encryption: " + Arrays.toString(getMessage().getBytes()));
        
        //byte[] msgBytes = getMessage().getBytes();
        
        Cipher ciph = Cipher.getInstance("RSA/ECB/NoPadding");
        ciph.init(Cipher.ENCRYPT_MODE, pubKey);
        SealedObject so = new SealedObject(getMessage(),ciph);
        
        //this.setMsgPayload(ciph.doFinal(msgBytes));
        //System.out.println("Before encryption: " + Arrays.toString(getMsgPayload()));
        setEncrypted(true);
    }
    
    public void decrypt(PrivateKey privKey) throws 
            NoSuchAlgorithmException, 
            NoSuchPaddingException, 
            InvalidKeyException, 
            IllegalBlockSizeException, 
            BadPaddingException {
        Cipher ciph = Cipher.getInstance("RSA/ECB/NoPadding");
        ciph.init(Cipher.DECRYPT_MODE, privKey);
        byte[] decrypted = ciph.doFinal(getMsgPayload());
        setMessage(Arrays.toString(decrypted));
        
        //setDecrypted? Is that necessary?
    }
    
    public void sign(KeyPair kp) throws 
            NoSuchAlgorithmException, 
            InvalidKeyException, 
            SignatureException 
    {
        if(isEncrypted() != true || getMsgPayload() == null || getMsgPayload().length < 1) {
            throw new RuntimeException("Had no payload to sign!");
        }
        Signature sign = Signature.getInstance("RSA");
        sign.initSign(kp.getPrivate());
        sign.update(getMsgPayload());
        this.setMsgSignature(sign.sign());
        this.setSigned(true);
    }

    /**
     * @return the msgPayload
     */
    byte[] getMsgPayload() {
        return msgPayload;
    }

    /**
     * @param msgPayload the msgPayload to set
     */
    void setMsgPayload(byte[] msgPayload) {
        this.msgPayload = msgPayload;
    }

    /**
     * @return the encrypted
     */
    boolean isEncrypted() {
        return encrypted;
    }

    /**
     * @param encrypted the encrypted to set
     */
    void setEncrypted(boolean encrypted) {
        this.encrypted = encrypted;
    }

    /**
     * @return the msgSignature
     */
    byte[] getMsgSignature() {
        return msgSignature;
    }

    /**
     * @param msgSignature the msgSignature to set
     */
    void setMsgSignature(byte[] msgSignature) {
        this.msgSignature = msgSignature;
    }

    /**
     * @return the signed
     */
    boolean isSigned() {
        return signed;
    }

    /**
     * @param signed the signed to set
     */
    void setSigned(boolean signed) {
        this.signed = signed;
    }
    
}
